import axios from 'axios';
//import { stringify } from 'qs';
import { isType } from '@utils';

/**
 * 封装axios请求 { get、post }
 * 1. timeout: 默认超时时间为 20000
 * 2. Content-Type: 默认为 application/json; charset=UTF-8
 */
let request = {};

/* 注射器 */
let injectors = [];

/* 接收器 */
let receivers = [];
console.log('@util request-begin', request, new Date().Format('mm:ss'));
const instance = axios.create({
  withCredentials: false,
  timeout: 20000,
  headers: {
    'Content-Type': 'application/json; charset=UTF-8'
  }
});
console.log('@util request-create', request);
instance.interceptors.request.use(
  (config) => {
    if (/^application\/x-www-form-urlencoded/.test(config.headers['Content-Type'])) {
      config.data = JSON.stringify(config.data);
    }

    // 执行注射器
    for (let i = 0; i < injectors.length; i++) {
      console.log('@util for injection', new Date().Format('mm:ss'));
      isType(injectors[i]) === 'Function' && injectors[i](config);
    }

    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);
console.log('@util request-interceptors.request', request, new Date().Format('mm:ss'));
instance.interceptors.response.use(
  (response) => {
    // 执行接收器
    for (let i = 0; i < receivers.length; i++) {
      isType(receivers[i]) === 'Function' && receivers[i](response);
    }

    return response.data;
  },
  (error) => {
    // 执行接收器
    for (let i = 0; i < receivers.length; i++) {
      isType(receivers[i]) === 'Function' && receivers[i](error);
    }

    return Promise.reject(error);
  }
);
console.log('@util request-interceptors.response', request);
/**
 * 设置注射器，发送请求前对headers修改
 * @param {Function} injector
 */
request.setInjector = function(injector) {
  if (isType(injector) !== 'Function') throw TypeError('Expected type is method');
  console.log('@util setInjection', new Date().Format('mm:ss'));
  injectors = [injector];
};

/**
 * 设置接收器，请求接收前对数据进行修改
 * @param {Function} receiver
 */
request.setReceiver = function(receiver) {
  if (isType(receiver) !== 'Function') throw TypeError('Expected type is method');
  receivers = [receiver];
};

/**
 *
 * @param {String} url
 * @param {Object} [params = {}]
 * @param {String | Object} [config] contentType | Config
 * @returns {Promise<AxiosResponse<T>>}
 */
request.get = function(url, params = {}, config) {
  if (isType(config) !== 'Object') {
    config = {
      headers: {
        'Content-Type': config
      },
      params
    };
  } else {
    config = Object.assign(config, { params });
  }
  return instance.get(url, config);
};

/**
 *
 * @param {String} url
 * @param {Object} [params = {}]
 * @param {String | Object} [config] contentType | Config
 * @returns {Promise<AxiosResponse<T>>}
 */
request.post = function(url, params = {}, config) {
  if (isType(config) === 'String') {
    config = {
      headers: {
        'Content-Type': config
      }
    };
  }
  return instance.post(url, params, config);
};
console.log('@util request', request, new Date().Format('mm:ss'));
export default request;
